package com.hup.sidebar.view;

import android.annotation.SuppressLint;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hup.sidebar.R;
import com.hup.sidebar.SideBarApplication;
import com.hup.sidebar.constant.PieFunctionConstant;
import com.hup.sidebar.framework.model.BaseConfig;
import com.hup.sidebar.framework.model.SpFieldHandler;
import com.hup.sidebar.framework.util.ToastUtil;
import com.hup.sidebar.model.AppConfig;
import com.hup.sidebar.model.MultiPieFunction;
import com.hup.sidebar.service.ActivationFloaterService;
import com.hup.sidebar.view.component.UndoManager;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * 配置导入/导出
 *
 * @author hugan
 * @date 2025/11/14
 */
@SuppressLint("NonConstantResourceId")
public class ConfigExportActivity extends AppCompatActivity {
    private static final String TAG = ConfigExportActivity.class.getSimpleName();

    @BindView(R.id.btnDefault)
    Button btnDefault;
    @BindView(R.id.txtContent)
    EditText txtContent;

    private AppConfig appConfig;
    private UndoManager undoManager;
    private final AtomicBoolean contentEdited = new AtomicBoolean();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate: ");
        appConfig = SideBarApplication.getBean(AppConfig.class);

        setContentView(R.layout.config_export_activity);
        ButterKnife.bind(this);
        txtContent.setText(JSON.toJSONString(appConfig, true));

        //监听
        undoManager = UndoManager.setUndoManager(txtContent);
        undoManager.setMaxHistory(80);
        txtContent.setOnFocusChangeListener((v, hasFocus) -> {
            if (hasFocus) {
                //延迟执行 确保光标等
                txtContent.post(() -> txtContent.selectAll());
            }
        });
        txtContent.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                contentEdited.set(true);
            }
        });
        btnDefault.setOnClickListener(v -> {
            BaseConfig config = new AppConfig().loadAll(this, true);
            String str = JSON.toJSONString(config, true);
            txtContent.setText(str);
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.common_editor_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.menu_undo) {
            undoManager.undo();
        } else if (item.getItemId() == R.id.menu_redo) {
            undoManager.redo();
        } else if (item.getItemId() == R.id.menu_save) {
            Log.d(TAG, "onOptionsItemSelected: menu_save");
            doSave();
        }
        return true;
    }

    @Override
    public void onBackPressed() {
        //Log.i(TAG, "onBackPressed: ");
        if (!contentEdited.get()) {
            SideBarApplication.executeIfExist(ActivationFloaterService.class, service -> service.setActivationVisible(false));
            super.onBackPressed();
            return;
        }
        new AlertDialog.Builder(this)
                .setTitle(R.string.cancel_save_title)
                .setPositiveButton(R.string.confirm, (dialog1, which) -> {
                    contentEdited.set(false);
                    onBackPressed();
                })
                .setNegativeButton(R.string.cancel, null)
                .create().show();
    }

    private void doSave() {
        try {
            ArrayList<MultiPieFunction> functionsOld = appConfig.getFunctions();

            /*
            简单校验: 字段类型,取值越界
            - 出现异常时,不会修改 appConfig
             */
            AppConfig test = JSON.parseObject(txtContent.getText().toString(), AppConfig.class);
            test.applyPieColor();
            SimpleDateFormat formatter = new SimpleDateFormat(test.noteDateFormat, Locale.getDefault());
            formatter.format(new Date());
            Log.i(TAG, "doSave: 简单校验通过");

            /*
            赋值,保存
            - 直接修改 appConfig
            - 不会修改 值是null的字段[删除字段,修改字段名]
            - 此处开始到结束,应该不会有异常;
            - 但是,一旦有异常, appConfig也已被修改(保底是不会持久化, 但此时用户直接返回时, appConfig和SharedPreferences 会数据不一致)
             */
            Editor editor = appConfig.getSp(this).edit();
            JSONObject json = (JSONObject) JSON.parse(txtContent.getText().toString());
            Map<String, SpFieldHandler> mapper = AppConfig.getFieldMapper(AppConfig.class);
            for (Entry<String, SpFieldHandler> entry : mapper.entrySet()) {
                String fieldName = entry.getKey();
                Object value = json.get(fieldName);
                if (value != null) {
                    if (fieldName.equals("functions")) {
                        value = ((JSONArray) value).toJavaList(MultiPieFunction.class);
                    }
                    SpFieldHandler handler = entry.getValue();
                    handler.batchSet(appConfig, value, editor);
                }
            }
            appConfig.applyPieColor();
            appConfig.noteDateFormatter = formatter;

            // 更新组件
            SideBarApplication.executeIfExist(ActivationFloaterService.class, ActivationFloaterService::onActivationConfigUpdated);
            SideBarApplication.executeIfExist(ActivationFloaterService.class, service -> service.setActivationVisible(true));
            SideBarApplication.executeIfExist(ActivationFloaterService.class, ActivationFloaterService::onPieConfigUpdated);
            PieFunctionConstant.initFunctions(appConfig);

            //成功后,释放旧对象
            if (functionsOld != appConfig.functions) {
                for (MultiPieFunction function : functionsOld) {
                    PieFunctionConstant.releaseIcon(function.normal);
                    PieFunctionConstant.releaseIcon(function.longPress);
                }
            }

            //持久化
            editor.apply();
            contentEdited.set(false);
            ToastUtil.long_(getString(R.string.config_export_saved));
        } catch (Exception e) {
            String raw = e.getMessage();
            if (raw == null) raw = "";
            if (raw.length() > 100) raw = raw.substring(0, 100);//处理 raw含整个json字符串
            String msg = getString(R.string.config_export_input_error, raw);
            Log.e(TAG, "doSave: " + msg);
            ToastUtil.long_(msg);
        }
    }


}
